1. Fabrik 3.9 has been released. If you have updated Joomla to 3.9, this is a required update.
    Dismiss Notice

Add guess link to phone app

Discussion in 'Community' started by lcollong, Feb 13, 2020 at 4:56 PM.

  1. lcollong

    lcollong FabriKant d'applications web

    Level: Community
    Hi,

    I had the need to let a phone number field act as a direct call when Fabrik's app is used from a smartphone.
    The "guess link" standard feature is building a link but without using the "phone possibility" (href="tel:010101010").

    I've modified the file plugins/fabrik_element/field/field.php. If a field element is set to "input type: phone Number" in advanced tab and guess link is set to yes, it makes the phone number click launching the phone app.

    Maybe it could also be achieved with the JLayouts ?

    Here is my code. I could make a github request but one may do it a better way (fabrik helper ?)....

    PHP:
     
     protected function _guessLinkType(&$value, $data)
        {
            $params = $this->getParams();

            if ($params->get('guess_linktype') == '1')
            {
                $w = new FabrikWorker;
                $opts = $this->linkOpts();
                $title = $params->get('link_title', '');
                $attrs = $params->get('link_attributes', '');
               
                $inputType = $params->get('password');  /////<----- ADDED LINE

                if (!empty($attrs))
                {
                    $attrs = $w->parseMessageForPlaceHolder($attrs);
                    $attrs = explode(' ', $attrs);

                    foreach ($attrs as $attr)
                    {
                        list($k, $v) = explode('=', $attr);
                        $opts[$k] = trim($v, '"');
                    }
                }
                else
                {
                    $attrs = array();
                }

                if ((new MediaHelper)->isImage($value))
                {
                    $alt = empty($title) ? '' : 'alt="' . strip_tags($w->parseMessageForPlaceHolder($title, $data)) . '"';
                    $value = '<img src="' . $value . '" ' . $alt . ' ' . implode(' ', $attrs) . ' />';
                }
    ///// begin of ADDED BLOCK          
                elseif ($inputType == '2') // if input type is "phone number" add a smartphone link to call the phone number
                {
                    $value = '<a href="tel:' . preg_replace('/\D/', '', $value) . '">'.$value.'</a>';
                }
    ///// end of ADDED BLOCK          
                else
                {
                    if (FabrikWorker::isEmail($value) || JString::stristr($value, 'http'))
                    {
                    }
                    elseif (JString::stristr($value, 'www.'))
                    {
                        $value = 'http://' . $value;
                    }

                    if ($title !== '')
                    {
                        $opts['title'] = strip_tags($w->parseMessageForPlaceHolder($title, $data));
                    }

                    $label = FArrayHelper::getValue($opts, 'title', '') !== '' ? $opts['title'] : $value;

                    $value = FabrikHelperHTML::a($value, $label, $opts);
                }
            }
        }
    If any better suggestions ?
     
  2. lousyfool

    lousyfool Active Member

    Level: Community
    Sorry, but why? In both iOS and Android, a tap on any phone number in a browser let's me easily call the number...
     
  3. lcollong

    lcollong FabriKant d'applications web

    Level: Community
    At least in my case, the phone number is inactive. Tapping on it has no effect. May be a question of element type (text vs integer ?) or template or browser version... I don't know... I heard that firefox is guessing it. I'm using chrome on Android. And several other users are also complaining.
    But with this special href link, it launches the phone app directly with the phone number in all circumstances. One tap on the phone, one tab on the call button and that's it ! Your're calling the contact. Small change, great improvement !
     
  4. lousyfool

    lousyfool Active Member

    Level: Community
    Curious, I just checked again. You're right, seems only iOS Safari seems to interpret any "not too short" number in text, including the ones with spaces and without +, as phone number and highlights them as link, while other browsers and Android are pickier (or more stubborn?). In iOS, Google Chrome even ignores +xx xxxx xxxx or +xxxxxxxxxx formats.

    So, yeah, if your application depends on it, you want to do something like what you're doing.
     
  5. troester

    troester Well-Known Member Staff Member

    Level: Community
    To keep the title and attribute features I would do (but I didn't test)
    Code (Text):

    protected function _guessLinkType(&$value, $data)
        {
            $params = $this->getParams();

            if ($params->get('guess_linktype') == '1')
            {
                $w = new FabrikWorker;
                $opts = $this->linkOpts();
                $title = $params->get('link_title', '');
                $attrs = $params->get('link_attributes', '');
             
                $inputType = $params->get('password');  /////<----- ADDED LINE

                if (!empty($attrs))
                {
                    $attrs = $w->parseMessageForPlaceHolder($attrs);
                    $attrs = explode(' ', $attrs);

                    foreach ($attrs as $attr)
                    {
                        list($k, $v) = explode('=', $attr);
                        $opts[$k] = trim($v, '"');
                    }
                }
                else
                {
                    $attrs = array();
                }

                if ((new MediaHelper)->isImage($value))
                {
                    $alt = empty($title) ? '' : 'alt="' . strip_tags($w->parseMessageForPlaceHolder($title, $data)) . '"';
                    $value = '<img src="' . $value . '" ' . $alt . ' ' . implode(' ', $attrs) . ' />';
                }
           
                else
                {
                    if (FabrikWorker::isEmail($value) || JString::stristr($value, 'http'))
                    {
                    }
                    elseif (JString::stristr($value, 'www.'))
                    {
                        $value = 'http://' . $value;
                    }
    ///// begin of ADDED BLOCK        
                   elseif ($inputType == '2') // if input type is "phone number" add a smartphone link to call the phone number
                   {
                         $value = 'tel:' . preg_replace('/\D/', '', $value);
                    }
    ///// end of ADDED BLOCK

                    if ($title !== '')
                    {
                        $opts['title'] = strip_tags($w->parseMessageForPlaceHolder($title, $data));
                    }

                    $label = FArrayHelper::getValue($opts, 'title', '') !== '' ? $opts['title'] : $value;

                    $value = FabrikHelperHTML::a($value, $label, $opts);
                }
            }
        }
     
  6. lcollong

    lcollong FabriKant d'applications web

    Level: Community
    Good point. However, I have to test again (last 3 lines) in order to preserve the original value as label otherwise it shows the whole url without white space which is not comfortable. Also my version show a "tel" label when the field is empty.... still to be tuned ! :)

    PHP:

    protected function _guessLinkType(&$value, $data)
        {
            $params = $this->getParams();

            if ($params->get('guess_linktype') == '1')
            {
                $w = new FabrikWorker;
                $opts = $this->linkOpts();
                $title = $params->get('link_title', '');
                $attrs = $params->get('link_attributes', '');
           
                $inputType = $params->get('password');  /////<----- ADDED LINE

                if (!empty($attrs))
                {
                    $attrs = $w->parseMessageForPlaceHolder($attrs);
                    $attrs = explode(' ', $attrs);

                    foreach ($attrs as $attr)
                    {
                        list($k, $v) = explode('=', $attr);
                        $opts[$k] = trim($v, '"');
                    }
                }
                else
                {
                    $attrs = array();
                }

                if ((new MediaHelper)->isImage($value))
                {
                    $alt = empty($title) ? '' : 'alt="' . strip_tags($w->parseMessageForPlaceHolder($title, $data)) . '"';
                    $value = '<img src="' . $value . '" ' . $alt . ' ' . implode(' ', $attrs) . ' />';
                }
         
                else
                {
                    if (FabrikWorker::isEmail($value) || JString::stristr($value, 'http'))
                    {
                    }
                    elseif (JString::stristr($value, 'www.'))
                    {
                        $value = 'http://' . $value;
                    }
    ///// begin of ADDED BLOCK      
                   elseif ($inputType == '2') // if input type is "phone number" add a smartphone link to call the phone number
                   {
                         $label = $value;
                         $value = 'tel:' . preg_replace('/\D/', '', $value);
                    }
    ///// end of ADDED BLOCK

                    if ($title !== '')
                    {
                        $opts['title'] = strip_tags($w->parseMessageForPlaceHolder($title, $data));
                    }

                    $newValue = $inputType == '2' ? $label : $value;   // added extra test
                 
                    $label = FArrayHelper::getValue($opts, 'title', '') !== '' ? $opts['title'] : $newValue; // in order to keep original value

                    $value = FabrikHelperHTML::a($value, $label, $opts);
                }
            }
        }
     
  7. lcollong

    lcollong FabriKant d'applications web

    Level: Community
    My final contribution which seems to work in all case....

    PHP:

        protected function _guessLinkType(&$value, $data)
        {
            $params = $this->getParams();

            if ($params->get('guess_linktype') == '1')
            {
                $w = new FabrikWorker;
                $opts = $this->linkOpts();
                $title = $params->get('link_title', '');
                $attrs = $params->get('link_attributes', '');

    /////<----- ADDED LINES        
                $inputType = $params->get('password');
                $telHref  = false;
    /////----->
                if (!empty($attrs))
                {
                    $attrs = $w->parseMessageForPlaceHolder($attrs);
                    $attrs = explode(' ', $attrs);

                    foreach ($attrs as $attr)
                    {
                        list($k, $v) = explode('=', $attr);
                        $opts[$k] = trim($v, '"');
                    }

                }
                else
                {
                    $attrs = array();
                }

                if ((new MediaHelper)->isImage($value))
                {
                    $alt = empty($title) ? '' : 'alt="' . strip_tags($w->parseMessageForPlaceHolder($title, $data)) . '"';
                    $value = '<img src="' . $value . '" ' . $alt . ' ' . implode(' ', $attrs) . ' />';
                }
         
                else
                {
                    if (FabrikWorker::isEmail($value) || JString::stristr($value, 'http'))
                    {
                    }
                    elseif (JString::stristr($value, 'www.'))
                    {
                        $value = 'http://' . $value;
                    }
    ///// begin of ADDED BLOCK      
                    elseif ($inputType == '2' && !empty($value))
                    // if input type is "phone number" add a smartphone link to call the phone number in one click
                    {
                        $telHref = true;
                        $label = $value;
                        $value = 'tel:' . preg_replace('/\D/', '', $value);
                    }
    ///// end of ADDED BLOCK

                    if ($title !== '')
                    {
                        $opts['title'] = strip_tags($w->parseMessageForPlaceHolder($title, $data));
                    }

                    $newValue = $telHref ? $label : $value;  ////// added line (preserve original value as label)
                   
                    $label = FArrayHelper::getValue($opts, 'title', '') !== '' ? $opts['title'] : $newValue;  ///// modified line

                    $value = FabrikHelperHTML::a($value, $label, $opts);
                }
            }
        }
     

Share This Page